#!/usr/bin/evn python
# -*- coding: utf-8 -*-
"""
-------------------------------------------------
   文件名称 :     __init__.py
   文件功能描述 :   功能描述
   创建人 :       小钟同学
   创建时间 :          2021/12/28
-------------------------------------------------
   修改描述-2021/12/28:
-------------------------------------------------
"""

import warnings
from afast_core.core_tools.modules_helper import find_modules, import_string2


def setup_batch_scan_iter_api_router(app_or_api_router, model_path, key_attribute='router', include_packages=True,
                                     recursive=True, is_loger_route=True):
    '''
    批量加载路由
    :param app_or_api_router: 是哪个对象需要进行包含路由，是app还是APIRouter
    :param model_path: 扫描的API的模块目录
    :param key_attribute: 扫描的api属性名
    # :param include_packages: 是否包含__init__
    :param recursive:是否递归扫描，
    :param is_loger_route: 是否给扫描出来的模块动态添加自定义的路由ContextLogerRoute类
    :return:
    '''
    modules = find_modules(model_path, include_packages=include_packages, recursive=recursive)
    try:
        for name in modules:
            module = import_string2(name)
            if hasattr(module, key_attribute):
                router = getattr(module, key_attribute)
                if is_loger_route:
                    pass
                    # 嵌套蓝图模块导入的时候，这里会失效，需要在蓝图模块手动的进行添加
                    # router.route_class = ContextLogerRoute
                    # setattr(router, 'route_class', ContextLogerRoute)  # 则添加属性到对象中
                # print("模塊：",name,router,id(router))
                app_or_api_router.include_router(router)

    except Exception as e:
        print('导入时候，出现异常！检测是否存在表单类型错误！', e)
        pass
        import traceback
        traceback.print_exc(e)


def setup_batch_scan_iter_nesting_log_router(app_or_api_router, model_path, key_attribute='router',
                                             include_packages=True, recursive=True):
    '''
    批量加载路由
    :param app_or_api_router: 是哪个对象需要进行包含路由，是app还是APIRouter
    :param model_path: 扫描的API的模块目录
    :param key_attribute: 扫描的api属性名
    # :param include_packages: 是否包含__init__
    :param recursive:是否递归扫描，
    :param is_loger_route: 是否给扫描出来的模块动态添加自定义的路由ContextLogerRoute类
    :return:
    '''
    modules = find_modules(model_path, include_packages=include_packages, recursive=recursive)
    try:
        for name in modules:
            module = import_string2(name)
            if hasattr(module, key_attribute):
                router = getattr(module, key_attribute)
                if router and hasattr(router, '_all_include_router'):
                    router = getattr(router, '_all_include_router')()
                # 要记得重命名，避免多模块找扫描出来同一个，重复添加了多个路由！问题
                app_or_api_router.include_router(router)

    except Exception as e:
        # print('导入时候，出现异常！检测是否存在表单类型错误！',e)
        # import traceback
        # traceback.print_exc(e)
        from loguru import logger
        logger.exception(e)
        pass


def setup_batch_scan_iter_api_router_vtext(app_or_api_router, model_path, key_attribute='router', include_packages=True,
                                           recursive=True, is_loger_route=True):
    '''
    简化批量加载模板
    :param app_or_api_router:
    :param model_path:
    :param key_attribute:
    :param include_packages:
    :param recursive:
    :param is_loger_route:
    :return:
    '''
    # 标记函数或类为废弃
    warnings.warn("some_old_function is deprecated", DeprecationWarning)
    modules = find_modules(model_path, include_packages=include_packages, recursive=recursive)
    try:
        for name in modules:
            module = import_string2(name)
            if hasattr(module, key_attribute):
                router = getattr(module, key_attribute)
                if is_loger_route:
                    pass
                    # router.route_class = ContextLogerRoute
                app_or_api_router.include_router(router)
    except Exception as e:
        # print('导入时候，出现异常！检测是否存在表单类型错误！')
        import traceback
        traceback.print_exc(e)
        pass


def setup_batch_scan_api_model(app, project_name, api_model='apis', key_attribute='bp', is_loger_route=True):
    '''
    自动的导入的蓝图模块
    示例：
    setup_batch_scan_api_model(core_app=core_app, project_name='rights', api_model='apis', key_attribute='api_router',is_loger_route=True)
    :param app:
    :return:
    '''
    # 标记函数或类为废弃
    warnings.warn("some_old_function is deprecated", DeprecationWarning)
    if not app:
        warnings.warn('路由注册失败,需要传入Fastapi对象实例')
        return None
    if project_name:
        # include_packages 这个设置为True很关键，它包含了 检测 对于的_init__内的属性，这个对于外层的遍历的来说很关键
        modules = find_modules(f'{project_name}.{api_model}', include_packages=True, recursive=True)
        try:
            for name in modules:
                module = import_string2(name)
                # 只找某个模块开始的，避免无意义的其他扫描
                # if not name.endswith(scan_name):
                #     continue
                if hasattr(module, key_attribute):
                    # apps.register_blueprint(module.mmpbp)
                    # lantu = getattr(module,key_attribute)
                    router = getattr(module, key_attribute)
                    # 已经全局挂载还需要吗？
                    # router.route_class = ContextLogerRoute
                    if is_loger_route:
                        pass
                        # router.route_class = ContextLogerRoute
                    app.include_router(router)
        except:
            print('导入时候，出现异常！检测是否存在表单类型错误！')
            pass
    else:
        warnings.warn('路由注册失败,外部项目名称还没定义')


def import_submodules(app, module):
    import importlib
    import sys
    import pkgutil
    """Import all submodules of a module, recursively."""
    for loader, module_name, is_pkg in pkgutil.walk_packages(
            module.__path__, module.__name__ + '.'):
        importlib.import_module(module_name)
        try:
            app.include_router(getattr(sys.modules[module_name], 'router'))
        except Exception as err:
            print(module_name + " : " + err)
            continue
